/**
 * 
 */
package jvs.vfs.opt.home;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.ArrayList;

import jvs.vfs.ContentTypes;
import jvs.vfs.IFile;
import jvs.vfs.IFileBaseImpl;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

/**
 * @author qiangli
 * 
 */
public class LauncherFileImpl extends IFileBaseImpl {

	private static final String[] LIST = { "/application", "/livefolder",
			"/shortcut", "/userfolder", /*TBD "/widget", */};

	private static final int LIST_APP = 0;
	private static final int LIST_LIVE = 1;
	private static final int LIST_SHORTCUT = 2;
	private static final int LIST_USER = 3;
	private static final int LIST_WIDGET = 4;

	private static Loader loader = null;

	private static final String LOG_TAG = "LauncherFileImpl";

	synchronized private static void loadReset() {
		// set loader to null to signal a reload is required
		loader = null;
	}

	synchronized private static void loadAll() {
		if (loader != null) {
			return;
		}
		loader = Loader.getInstance();
		Context ctx = (Context) fs.getContext();
		if (ctx == null) {
			return;
		}
		loader.load(ctx);
	}

	public static int match(String s) {
		String[] fl = LIST;
		int len = fl.length;
		for (int i = 0; i < len; i++) {
			if (s.equals(fl[i])) {
				return i;
			}
		}
		return -1;
	}

	public static int matchStartsWith(String s) {
		String[] fl = LIST;
		int len = fl.length;
		for (int i = 0; i < len; i++) {
			if (s.startsWith(fl[i])) {
				return i;
			}
		}
		return -1;
	}

	private static String[] toArray(ArrayList<ItemInfo> list) {
		int sz = list.size();
		String[] sa = new String[sz];
		for (int i = 0; i < sz; i++) {
			ItemInfo fi = list.get(i);
			sa[i] = fi.id;
		}
		return sa;
	}

	private ItemInfo item = null;

	private boolean isFolder;
	
	private ArrayList<ItemInfo> userFolders;

	/**
	 * @param uri
	 */
	public LauncherFileImpl(URI uri) {
		super(uri);
		//
		isFolder = true;
		String p = path(uri);
		if (DEBUG) {
			Log.d(LOG_TAG, "uri: " + uri + " p: " + p);
		}
		item = null;
		if (p.equals("/")) {
			// root
			return;
		}
		int t = match(p);
		if (t != -1) {
			// top folders
			return;
		}
		//
		String itemId = name(p);
		Context ctx = (Context) fs.getContext();
		item = Loader.findItem(ctx, itemId);
		if (DEBUG) {
			Log.d(LOG_TAG, "item id: " + itemId + " item: " + item);
		}
		if (item instanceof UserFolderInfo) {
			isFolder = true;
		} else {
			isFolder = false;
		}
	}

	private LauncherFileImpl(URI uri, ItemInfo info) {
		super(uri);
		//
		if (DEBUG) {
			Log.d(LOG_TAG, "uri: " + uri + " info: " + info);
		}
		this.item = info;
		if (info instanceof UserFolderInfo) {
			this.isFolder = true;
		} else {
			this.isFolder = false;
		}
	}

	@Override
	public boolean canExecute() {
		return (isFolder == false);
	}

	@Override
	public boolean canRead() {
		return true;
	}

	@Override
	public boolean canWrite() {
		return false;
	}

	@Override
	public boolean create() {
		return false;
	}

	@Override
	public boolean delete() {
		return false;
	}

	@Override
	public boolean execute() {
		if (item == null) {
			return false;
		}
		Context ctx = (Context) fs.getContext();
		try {
			Intent i = item.intent;
			// construct intent for widgets
			if (item instanceof AppWidgetInfo) {
				i = new Intent(Intent.ACTION_VIEW);
				i.setType(ContentTypes.APP_WIDGET);
				//
				AppWidgetInfo w = (AppWidgetInfo) item;
				Intent pending = new Intent(Intent.ACTION_VIEW);
				pending.setComponent(w.provider);
				//
				i.putExtra("appwidget_intent", pending);
				i.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, w.appWidgetId);
			} else if (i == null) {
				return false;
			}
			i.setFlags(i.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
			ctx.startActivity(i);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public boolean exists() {
		return true;
	}

	@Override
	public String getDisplayName() {
		ItemInfo i = item;
		if (i != null) {
			return (i.title == null ? i.id : i.title);
		}
		return super.getDisplayName();
	}

	@Override
	public InputStream getInputStream() {
		return null;
	}

	@Override
	public String getName() {
		if (item != null) {
			return item.id;
		}
		return super.getName();
	}

	@Override
	public OutputStream getOutputStream() {
		return null;
	}

	@Override
	public String getPhoneticName() {
		ItemInfo i = item;
		if (i != null) {
			return (i.title == null ? i.id : i.title);
		}
		return super.getPhoneticName();
	}

	@Override
	public String getSortKey() {
		ItemInfo i = item;
		if (i != null) {
			return (i.title == null ? i.id : i.title);
		}
		return super.getSortKey();
	}

	@Override
	public boolean isDirectory() {
		return (isFolder);
	}

	@Override
	public boolean isEmpty() {
		if (isFolder && item == null) {
			// top folders
			return false;
		}
		String p = path(uri);
		int t = match(p);
		loadAll();
		ArrayList<ItemInfo> al = null;
		switch (t) {
		case LIST_APP:
			al = loader.appList;
			break;
		case LIST_WIDGET:
			al = loader.widgetList;
			break;
		case LIST_SHORTCUT:
			al = loader.shortcutList;
			break;
		case LIST_LIVE:
			al = loader.liveFolderList;
			break;
		case LIST_USER:
			al = loader.userFolderList;
			break;
		default:
			// user folders
			if (item != null && item instanceof UserFolderInfo) {
				loadUserFolder();
				al = userFolders;
			}
		}
		return (al == null || al.size() == 0);
	}

	@Override
	public boolean isFile() {
		return (!isFolder);
	}

	@Override
	public boolean isLocal() {
		return true;
	}

	@Override
	public boolean isNative() {
		return false;
	}

	@Override
	public String[] list() {
		String p = path(uri);
		if (p.equals("/")) {
			return LIST;
		}
		int t = match(p);
		ArrayList<ItemInfo> al = null;
		loadAll();
		//
		switch (t) {
		case LIST_APP:
			al = loader.appList;
			break;
		case LIST_WIDGET:
			al = loader.widgetList;
			break;
		case LIST_SHORTCUT:
			al = loader.shortcutList;
			break;
		case LIST_LIVE:
			al = loader.liveFolderList;
			break;
		case LIST_USER:
			al = loader.userFolderList;
			break;
		default:
			//
			if (item != null && item instanceof UserFolderInfo) {
				loadUserFolder();
				al = userFolders;
			}
		}
		if (al == null) {
			return null;
		}
		return toArray(al);
	}

	@Override
	public IFile[] listFiles() {
		String p = path(uri);
		if (p.equals("/")) {
			return super.listFiles();
		}
		int t = match(p);
		ArrayList<ItemInfo> al = null;
		loadAll();
		//
		switch (t) {
		case LIST_APP:
			al = loader.appList;
			break;
		case LIST_WIDGET:
			al = loader.widgetList;
			break;
		case LIST_SHORTCUT:
			al = loader.shortcutList;
			break;
		case LIST_LIVE:
			al = loader.liveFolderList;
			break;
		case LIST_USER:
			al = loader.userFolderList;
			break;
		default:
			// user folder
			if (item != null && item instanceof UserFolderInfo) {
				loadUserFolder();
				al = userFolders;
			}
		}
		if (al == null) {
			return null;
		}
		int len = al.size();
		IFile[] rl = new IFile[len];
		for (int i = 0; i < len; i++) {
			ItemInfo fi = al.get(i);
			URI pu = uri.resolve(uri.getPath() + "/" + fi.id);
			rl[i] = new LauncherFileImpl(pu, fi);
		}
		return rl;
	}

	private void loadUserFolder() {
		if (userFolders != null) {
			return;
		}
		userFolders = new ArrayList<ItemInfo>();
		Context ctx = (Context) fs.getContext();
		Loader.loadUserFolder(ctx, item.id, userFolders);
	}

	@Override
	public boolean mkdir() {
		return false;
	}

	@Override
	public boolean move(URI uri) {
		return false;
	}

	@Override
	public void refresh() {
		loadReset();
	}

	@Override
	public Object getIcon() {
		if (item != null) {
			return item.icon;
		}
		//
		return super.getIcon();
	}

	@Override
	public String getContentType() {
		if (isFolder) {
			return ContentTypes.APP_FOLDER;
		}
		return ContentTypes.APP_INTENT;
	}

}
